package com.basic.library.utils.audio;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.fragment.app.FragmentActivity;

import com.basic.library.Interface.MCallback;
import com.basic.library.R;
import com.basic.library.utils.PermissionUtil;
import com.basic.library.utils.PreferencesUtils;

/**
 * @author yj
 * @description
 */
public class AudioRecordButton extends LinearLayout implements AudioManager.AudioStageListener {

    private static final int STATE_NORMAL = 1;
    private static final int STATE_RECORDING = 2;
    private static final int STATE_WANT_TO_CANCEL = 3;

    private static final int DISTANCE_Y_CANCEL = 50;

    private int mCurrentState = STATE_NORMAL;
    // 已经开始录音
    private boolean isRecording = false;

    private DialogManager mDialogManager;

    private AudioManager mAudioManager;

    private float mTime = 0;
    private long curTime = 0;
    // 是否触发了onlongclick，准备好了
    private boolean mReady;

    /**
     * 先实现两个参数的构造方法，布局会默认引用这个构造方法， 用一个 构造参数的构造方法来引用这个方法 * @param context
     */

    public AudioRecordButton(Context context) {
        this(context, null);
        // TODO Auto-generated constructor stub
    }

    TextView btn;

    public AudioRecordButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        View v = LayoutInflater.from(context).inflate(R.layout.base_chart_button, this, true);
        btn = (TextView) v.findViewById(R.id.btn);
        btn.setBackgroundResource(R.drawable.button_recordnormal);
        btn.setText(R.string.normal);
//		btn.setClickable(false);
//		btn.setFocusable(false);
        btn.setVisibility(View.GONE);

        mDialogManager = new DialogManager(getContext(), this);

        // 这里没有判断储存卡是否存在，有空要判断
        mAudioManager = AudioManager.getInstance();
        mAudioManager.setOnAudioStageListener(this);

        setOnLongClickListener(new OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {
                // TODO Auto-generated method
                if (!PermissionUtil.granted(getContext(), null, Manifest.permission.RECORD_AUDIO)) {
                    return false;
                }
                if (otherAction != null) {
                    otherAction.onclick();
                }
                mReady = true;
                mAudioManager.prepareAudio();//初始化录音，并生成随机录音文件名 执行wellPrepared
                return false;
            }
        });
        // TODO Auto-generated constructor stub
    }

    otherAction otherAction;

    public interface otherAction {
        public void onclick();
    }

    /**
     * 长按回调
     */
    public void setOnclick(otherAction o) {
        otherAction = o;
    }

    public static void saveIs_root(String is_root) {
        PreferencesUtils.setStringPreferences("is_root", "is_root", is_root);
    }

    public static String getIs_root() {
        return PreferencesUtils.getStringPreferences("is_root", "is_root", "");
    }

    /**
     * 录音完成后的回调，回调给activiy，可以获得mtime和文件的路径
     *
     * @author nickming
     */
    public interface AudioFinishRecorderListener {
        void onFinished(float seconds, String filePath);
    }

    private AudioFinishRecorderListener mListener;

    public void setAudioFinishRecorderListener(AudioFinishRecorderListener listener) {
        mListener = listener;
    }

    // 获取音量大小的runnable
    private Runnable mGetVoiceLevelRunnable = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            while (isRecording) {
                try {
                    Thread.sleep(100);
                    mTime += 0.1f;
                    mhandler.sendEmptyMessage(MSG_VOICE_CHANGE);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    };
    // 获取音量大小的runnable
    private Runnable mGetVoiceLevelRunnable1 = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            if (isRecording) {
                try {
//					Thread.sleep(100);
                    mTime += 0.1f;
                    //System.out.println(mTime);
                    mhandler.sendEmptyMessage(MSG_VOICE_CHANGE);
                    mhandler.postDelayed(this, 100);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    };

    // 准备三个常量
    private static final int MSG_AUDIO_PREPARED = 0X110;
    private static final int MSG_VOICE_CHANGE = 0X111;
    private static final int MSG_DIALOG_DIMISS = 0X112;

    private Handler mhandler = new Handler(Looper.getMainLooper()) {
        @SuppressLint("HandlerLeak")
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case MSG_AUDIO_PREPARED:
                    // 显示应该是在audio end prepare之后回调
                    mDialogManager.showRecordingDialog();
                    isRecording = true;
//				new Thread(mGetVoiceLevelRunnable).start();//第一次，出现获取录音权限的对话框时，时间长了会奔溃
                    mhandler.postDelayed(mGetVoiceLevelRunnable1, 0);
                    curTime = System.currentTimeMillis();
                    // 需要开启一个线程来变换音量
                    break;
                case MSG_VOICE_CHANGE:
                    mDialogManager.updateVoiceLevel(mAudioManager.getVoiceLevel(7));
                    break;
                case MSG_DIALOG_DIMISS:
                    mDialogManager.dimissDialog();
                    break;

            }
        }

        ;
    };

    public void dimiss() {
        mDialogManager.dimissDialog();
    }

    // 在这里面发送一个handler的消息
    @Override
    public void wellPrepared() {
        // TODO Auto-generated method stub
        mhandler.sendEmptyMessage(MSG_AUDIO_PREPARED);
    }

    /**
     * 直接复写这个监听函数
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        int action = event.getAction();
        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (action) {
            case MotionEvent.ACTION_CANCEL:
//			System.out.println("ACTION_CANCEL ");
                mAudioManager.cancel();
                mDialogManager.dimissDialog();
                mhandler.postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        mDialogManager.dimissDialog();
                    }
                }, 350);
                reset();// 恢复标志位
                break;
            case MotionEvent.ACTION_DOWN:
//			System.out.println("ACTION_DOWN ");
                changeState(STATE_RECORDING);
                break;
            case MotionEvent.ACTION_MOVE:
                //System.out.println("move");

                if (isRecording) {

                    // 根据x，y来判断用户是否想要取消
                    if (wantToCancel(x, y)) {//System.out.println("上滑消失界面");
                        changeState(STATE_WANT_TO_CANCEL);
                    } else {//System.out.println("复写");
                        changeState(STATE_RECORDING);
                    }

                }

                break;
            case MotionEvent.ACTION_UP:
//			System.out.println("ACTION_UP");
                // 首先判断是否有触发onlongclick事件，没有的话直接返回reset
                if (getIs_root().equals("1")) {
                    mDialogManager.dimissDialog();
                }
                if (!mReady) {
                    reset();
                    return super.onTouchEvent(event);
                }
                // 如果按的时间太短，还没准备好或者时间录制太短，就离开了，则显示这个dialog
                mTime = (System.currentTimeMillis() - curTime) / 1000f;
                if (!isRecording || mTime < 0.6f) {//System.out.println("时间短消失");
                    mDialogManager.tooShort();
                    mAudioManager.cancel();
                    mhandler.sendEmptyMessageDelayed(MSG_DIALOG_DIMISS, 1300);// 持续1.3s
                } else if (mCurrentState == STATE_RECORDING) {//正常录制结束

                    mDialogManager.dimissDialog();//System.out.println("消失");

                    mAudioManager.release();// release释放一个mediarecorder

                    if (mListener != null) {// 并且callbackActivity，保存录音

                        mListener.onFinished(mTime, mAudioManager.getCurrentFilePath());
                    }


                } else if (mCurrentState == STATE_WANT_TO_CANCEL) {
                    // cancel
                    mAudioManager.cancel();
                    mDialogManager.dimissDialog();
                }
                reset();// 恢复标志位

                break;

        }

        return super.onTouchEvent(event);
    }

    /**
     * 回复标志位以及状态
     */
    private void reset() {
        // TODO Auto-generated method stub
        isRecording = false;
        changeState(STATE_NORMAL);
        mReady = false;
        mTime = 0;
    }

    private boolean wantToCancel(int x, int y) {
        // TODO Auto-generated method stub

        if (x < 0 || x > getWidth()) {// 判断是否在左边，右边，上边，下边
            return true;
        }
        if (y < -DISTANCE_Y_CANCEL || y > getHeight() + DISTANCE_Y_CANCEL) {
            return true;
        }

        return false;
    }

    private void changeState(int state) {//System.out.println("按钮状态变化");
        // TODO Auto-generated method stub
        if (mCurrentState != state) {
            mCurrentState = state;
            switch (mCurrentState) {
                case STATE_NORMAL:
                    btn.setBackgroundResource(R.drawable.button_recordnormal);
                    btn.setText(R.string.normal);

                    break;
                case STATE_RECORDING:
                    if (!PermissionUtil.granted(getContext(), null, Manifest.permission.RECORD_AUDIO)) {
                        PermissionUtil.authorOnceWithGranted((FragmentActivity) getContext(), new MCallback<Boolean>() {
                            @Override
                            public void onResponse(Boolean aBoolean) {

                            }
                        }, Manifest.permission.RECORD_AUDIO);
                        reset();
                        return;
                    }
                    btn.setBackgroundResource(R.drawable.button_recording);
                    btn.setText(R.string.recording);
                    if (isRecording) {
                        mDialogManager.recording();
                        // 复写dialog.recording();
                    }
                    break;

                case STATE_WANT_TO_CANCEL:
                    btn.setBackgroundResource(R.drawable.button_recording);
                    btn.setText(R.string.want_to_cancle);
                    // dialog want to cancel
                    mDialogManager.wantToCancel();
                    break;

            }
        }

    }

//	@Override
//	public boolean onPreDraw() {
//		// TODO Auto-generated method stub
//		return false;
//	}

}